package com.zlt.appparking.service.impl;

import com.zlt.appparking.entity.*;
import com.zlt.appparking.mapper.*;
import com.zlt.appparking.service.AccessRecordService;
import com.zlt.appparking.utils.StringUtil;
import com.zlt.appparking.vo.AccessRecordVO;
import com.zlt.appparking.vo.ActiveUser;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class AccessRecordServiceImpl implements AccessRecordService {

    @Resource
    CameraMapper cameraMapper;
    @Resource
    AppointmentMapper appointmentMapper;
    @Resource
    UserVipMapper userVipMapper;

    @Resource
    AccessRecordMapper accessRecordMapper;

    @Resource
    CarAddressMapper carAddressMapper;

    @Resource
    LicenseMapper licenseMapper;

    @Resource
    VipTypeMapper vipTypeMapper;

    @Override
    public Object addRecord(String carNum, int id) {

        Camera camera = cameraMapper.selectByPrimaryKey(id);//查询摄像头数据
        AccessRecord accessRecord = new AccessRecord();
        if(camera != null){//若摄像头不为空
            if(camera.getcIsInto() == 0){//进
                //查询当前停车场车位数
                CarAddressExample carAddressExample = new CarAddressExample();
                carAddressExample.createCriteria().andPlIdEqualTo(camera.getPlId());
                List<CarAddress> carAddressList = carAddressMapper.selectByExample(carAddressExample);
                //设置进入时间
                accessRecord.setArIntoTime(new Date());
                //根据车牌号查出是否绑定用户
                LicenseExample licenseExample = new LicenseExample();
                licenseExample.createCriteria().andLNumEqualTo(carNum).andLStateEqualTo((byte) 3);
                List<License> licenseList = licenseMapper.selectByExample(licenseExample);
                CarAddress carAddress = carAddressList.get(0);
                if(licenseList == null || licenseList.size() < 1){//未绑定车牌，即游客
                    if(carAddress.getCaSurplus()>0){
                        carAddress.setCaSurplus(carAddress.getCaSurplus()-1);
                        carAddressMapper.updateByPrimaryKeySelective(carAddress);
                    }else{
                        return "车位已满";
                    }
                }else {
                    //处理预约
                    //todo 1.这里应该在预约表中新增车牌号字段，用车牌号去判断是否预约
                    //当前实现方式：通过carNum 查询用户信息，在通过用户信息查询预约信息
                    Appointment appointment = new Appointment();
                    AppointmentExample example = new AppointmentExample();
                    example.createCriteria().andPlIdEqualTo(camera.getPlId()).
                            andAuIdEqualTo(licenseList.get(0).getAuId()).andApStateEqualTo((byte) 0);
                    List<Appointment> appointmentList = appointmentMapper.selectByExample(example);
                    //为预约用户
                    if(appointmentList != null && appointmentList.size()>0){
                        appointment = appointmentList.get(0);
                        //todo 数据库更新后，需要修改代码
                        accessRecord.setArIsAppointment((byte) 1);//已预约
                        //更新预约表
                        appointment.setApState((byte) 3);
                        appointmentMapper.updateByPrimaryKey(appointment);

                    }else{//未预约，需对车位信息减一
                        if(carAddress.getCaSurplus()>0){
                            carAddress.setCaSurplus(carAddress.getCaSurplus()-1);
                            accessRecord.setArIsAppointment((byte) 0);
                            carAddressMapper.updateByPrimaryKeySelective(carAddress);
                        }else{
                            return "车位已满";
                        }
                    }
                    //处理vip
                    UserVipExample userVipExample = new UserVipExample();
                    userVipExample.createCriteria().andAuIdEqualTo(licenseList.get(0).getAuId()).andUvStateEqualTo((byte) 0);
                    List<UserVip> userVipList = userVipMapper.selectByExample(userVipExample);//用户vip信息
                    //vtid集合
                    List<Integer> vtid = new ArrayList<>();
                    userVipList.forEach( u -> {
                        vtid.add(u.getVtId());
                    });
                    //当前停车场vtid
                    VipTypeExample vipTypeExample = new VipTypeExample();
                    vipTypeExample.createCriteria().andPlIdEqualTo(camera.getPlId());
                    List<VipType> vipTypes = vipTypeMapper.selectByExample(vipTypeExample);

                    if (vipTypes != null && vipTypes.size()>0){
                        AccessRecord finalAccessRecord = accessRecord;
                        vtid.forEach(v -> {
                            if (vipTypes.get(0).getVtId().equals(v)){//说明该用户是当前停车场月租用户
                                finalAccessRecord.setVtId(v);
                            } else if(0 == v){//说明是平台vip
                                finalAccessRecord.setVtId(v);
                            }
                        });
                    }
                }
                accessRecord.setlNum(carNum);
//                accessRecord.setArIsAppointment();//根据数据表修改
                accessRecord.setPlId(camera.getPlId());
                //插入数据
                accessRecordMapper.insert(accessRecord);
                return 1;
            }else{//出

                AccessRecordExample accessRecordExample = new AccessRecordExample();
                accessRecordExample.createCriteria().andArOutTimeIsNull();//出时间为空
                accessRecordExample.setOrderByClause("ar_into_time desc");//进时间降序
                List<AccessRecord> accessRecordList = accessRecordMapper.selectByExample(accessRecordExample);

                BigDecimal totalPrice = new BigDecimal(0);
                if(accessRecordList != null){
                    accessRecord = accessRecordList.get(0);
                    accessRecord.setArOutTime(new Date());//出时间更新
//                    accessRecordMapper.updateByPrimaryKeySelective(accessRecord);
                    //更新停车场车位数量
                    CarAddressExample carAddressExample = new CarAddressExample();
                    carAddressExample.createCriteria().andPlIdEqualTo(camera.getPlId());
                    List<CarAddress> carAddressList = carAddressMapper.selectByExample(carAddressExample);
                    if(carAddressList != null && carAddressList.size()>0){
                        CarAddress carAddress = carAddressList.get(0);
                        carAddress.setCaSurplus(carAddress.getCaSurplus()+1);
                        carAddressMapper.updateByPrimaryKeySelective(carAddress);
                    }
                    //设置金额
                    if (accessRecord.getVtId() == null || accessRecord.getVtId() == 0){
                        try {
                            Long diffBetween = StringUtil.diffBetween(accessRecord.getArIntoTime(),accessRecord.getArOutTime());
                            diffBetween = diffBetween/1000/60;
                            int timeHours = 0;
                            if(diffBetween>=5){
                                timeHours = Integer.parseInt(diffBetween+"")/60+1;//停车时间
                            }
                            if(carAddressList != null){
                                CarAddress carAddress = carAddressList.get(0);
                                totalPrice = carAddress.getCaPrice().multiply(new BigDecimal(timeHours));
                                accessRecord.setArPayMoney(totalPrice.doubleValue());
                                accessRecordMapper.updateByPrimaryKeySelective(accessRecord);
                            }
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    } else {
                        accessRecord.setArPayMoney(0.0);
                        accessRecordMapper.updateByPrimaryKeySelective(accessRecord);
                    }
                }
                return totalPrice;
            }
        }
        return 0;
    }

    @Override
    public List<AccessRecordVO> selectRecord(String carNum) {
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();//当前登录人
        AccessRecordExample accessRecordExample = new AccessRecordExample();
        List<AccessRecordVO> accessRecordVOList = new ArrayList<>();
        if(activeUser == null){
            throw new RuntimeException("请登录后查询");
        }
        if (activeUser != null && carNum == null){
            LicenseExample licenseExample = new LicenseExample();
            licenseExample.createCriteria().andAuIdEqualTo(activeUser.getAuId());
            //查找车牌
            List<License> licenses = licenseMapper.selectByExample(licenseExample);
            List<String> lNums = new ArrayList<>();
            licenses.forEach( l -> {
                lNums.add(l.getlNum());
            });
            List<AccessRecord> accessRecords = accessRecordMapper.selectAllRecord(lNums);
            if (accessRecords != null && accessRecords.size() > 0){
                accessRecords.forEach( a -> {
                    AccessRecordVO accessRecordVO = new AccessRecordVO();
                    BeanUtils.copyProperties(a,accessRecordVO);
                    accessRecordVOList.add(accessRecordVO);
                });
            }
        } else {
            accessRecordExample.createCriteria().andLNumEqualTo(carNum);
            List<AccessRecord> accessRecords = accessRecordMapper.selectByExample(accessRecordExample);
            if (accessRecords != null && accessRecords.size() > 0){
                accessRecords.forEach( a -> {
                    AccessRecordVO accessRecordVO = new AccessRecordVO();
                    BeanUtils.copyProperties(a,accessRecordVO);
                    accessRecordVOList.add(accessRecordVO);
                });
            }
        }
        return accessRecordVOList;
    }
}
